import java.io.IOException;
import java.util.ArrayList;

import org.json.JSONException;

public class ClassifyAlgorithm {
	static int tec;
	static double tes;
	static String host;
	static Node categoryTree;

	public static void initialize(String hostName, int tecInput, double tesInput) {
		tec = tecInput;
		tes = tesInput;
		host = hostName;

		categoryTree = Node.creatCategoryTree("root");
	}

	public static void category(Node tree, double parentSpecificity, ArrayList<String> categories, String prefix) throws IOException, JSONException {
		boolean matched = false;
		if (tree.isLeaf)
		{
			categories.add(prefix + tree.name.substring(0, 1).toUpperCase()
					+ tree.name.substring(1));
			return;
		}

		// calculate ECoverage vector ECoverage(D,Ci)
		int[] resultECoverageVector = new int[tree.subCategory.size()];
		for (int i = 0; i < tree.subCategory.size(); i++) {
			resultECoverageVector[i] = calculateECoverage(tree.subCategory
					.get(i));
		}
		// calculate ESpecificity vector ESpecificity(D,Ci)
		double[] resultESpecificity = calculateESpecificity(resultECoverageVector, parentSpecificity);

		for (int j = 0; j < resultECoverageVector.length; j++) {
			System.out.println("Specificity for category:"
					+ tree.subCategory.get(j).name + " is "
					+ resultESpecificity[j]);
			System.out.println("Coverage for category:"
					+ tree.subCategory.get(j).name + " is "
					+ resultECoverageVector[j]);

			if (resultECoverageVector[j] >= tec && resultESpecificity[j] >= tes) {
				matched = true;
				category(tree.subCategory.get(j), resultESpecificity[j], categories, prefix + tree.name.substring(0, 1).toUpperCase()
								+ tree.name.substring(1) + "/");
			}

		}

		if (!matched)
			categories.add(prefix + tree.name.substring(0, 1).toUpperCase() + tree.name.substring(1));
	}

	private static double[] calculateESpecificity(int[] resultECoverageVector, double parentSpecificity) {
		// TODO Auto-generated method stub
		int resultTotal = 0;
		for (int i = 0; i < resultECoverageVector.length; i++)
			resultTotal = resultTotal + resultECoverageVector[i];
		double[] resultESpecificity = new double[resultECoverageVector.length];
		for (int j = 0; j < resultECoverageVector.length; j++)
			resultESpecificity[j] = (double) resultECoverageVector[j] * parentSpecificity
					/ resultTotal;
		return resultESpecificity;
	}

	private static int calculateECoverage(Node tree) throws IOException,
			JSONException {
		// TODO Auto-generated method stub
		int resultECoverage = 0;
		for (int i = 0; i < tree.keyWords.size(); i++) {
			resultECoverage = resultECoverage
					+ QueryExecutor.totalMatches(host, tree.name,
							tree.keyWords.get(i));
		}
		return resultECoverage;
	}

	public static ArrayList<String> getCategoryResult(String hostInput, int tecInput,
			double tesInput) throws IOException, JSONException {
		System.out.println("Classifying...");
		initialize(hostInput, tecInput, tesInput);
		ArrayList<String> categories = new ArrayList<String>();
		category(categoryTree, 1.0, categories, "");
		System.out.println("Classification:");
		for (String cls : categories)
			System.out.println(cls);
		return categories;
	}

	/*
	 * public static void main(String[] args) throws IOException, JSONException
	 * { ClassifyAlgorithm.getCategoryResult("diabetes.org", 100, 0.001); }
	 */
}
